package com.lb.bs.client.processor.handle.statics.second;

import com.alibaba.fastjson.JSON;
import com.lb.bs.client.annotation.LBUpdateClass;
import com.lb.bs.client.annotation.ProcessorMark;
import com.lb.bs.client.annotation.SingletonMark;
import com.lb.bs.client.repository.ScanStaticModel;
import com.lb.bs.client.callback.DefaultLogLevelUpdate;
import com.lb.bs.client.callback.UpdateCallBackService;
import com.lb.bs.client.factory.SingletonFactory;
import com.lb.bs.client.processor.ProcessorService;
import com.lb.bs.client.processor.enums.ProcessorType;
import com.lb.bs.client.repository.BeanHolder;
import com.lb.bs.client.repository.StoreCenter;
import com.lb.bs.client.util.CollectionUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * program: LB-BS-Client
 * author: bsworld.xie
 * create: 2019-12-11 16:36
 * description:
 */
@SingletonMark
@ProcessorMark(type = ProcessorType.SECOND_SYNC_UPDATE_CALL_BACK)
public class StaticSyncUpdateCallBackProcessor implements ProcessorService<ScanStaticModel> {
    private static final Logger logger = LoggerFactory.getLogger(StaticSyncUpdateCallBackProcessor.class);


    @Override
    public void process(ScanStaticModel scanStaticModel) {
        List<UpdateCallBackService> updateBeanMap = BeanHolder.getHolder().getUpdateCallBackBean();
        logger.info("StaticSyncUpdateCallBackProcessor.class,updateBeanMap:{}, scanStaticModel.updateClazzList:{}", new Object[]{JSON.toJSONString(updateBeanMap), JSON.toJSONString(scanStaticModel.getUpdateClazzList())});
        for (UpdateCallBackService updateCallBackService : updateBeanMap) {
            if (updateCallBackService == null) {
                continue;
            }
            Class<? extends UpdateCallBackService> clazz = updateCallBackService.getClass();
            LBUpdateClass[] annotationsByType = clazz.getAnnotationsByType(LBUpdateClass.class);
            if (annotationsByType == null || annotationsByType.length == 0) {
                continue;
            }
            Set<String> keySets = new HashSet<>();
            for (LBUpdateClass lbUpdateClass : annotationsByType) {
                String[] itemKeys = lbUpdateClass.itemKeys();
                keySets = Stream.of(itemKeys).collect(Collectors.toSet());
            }
            insertCallBackKey(keySets, updateCallBackService, false);
        }
        //major 对于日志相关的回调方法的设置，对于已经监听的常规的updateCallBack key则进行覆盖
        dealLogPath(scanStaticModel);
    }

    private void insertCallBackKey(Collection<String> keys, UpdateCallBackService updateCallBackService,boolean isLogPath) {
        Map<String, List<UpdateCallBackService>> itemKeyCallBackMap = StoreCenter.getInstance().getItemKeyCallBackMap();
        for (String key : keys) {
            List<UpdateCallBackService> callBackServiceList = itemKeyCallBackMap.get(key);
            if (isLogPath) {
                callBackServiceList = null;
            }
            if (callBackServiceList == null) {
                callBackServiceList = new ArrayList<>();
                itemKeyCallBackMap.put(key, callBackServiceList);
            }
            callBackServiceList.add(updateCallBackService);
        }
    }

    private void dealLogPath(ScanStaticModel scanStaticModel) {
        Map<String, String> groupLogPathMap = scanStaticModel.getGroupLogPathMap();
        if (CollectionUtils.isEmpty(groupLogPathMap)) {
            logger.info("dealLogPath(), groupLogPathMap is empty");
            return;
        }
        UpdateCallBackService logLevel = SingletonFactory.getInstance(DefaultLogLevelUpdate.class);
        insertCallBackKey(groupLogPathMap.values(), logLevel, true);
        Map<String, String> groupLogPathMapCenter = StoreCenter.getInstance().getGroupLogPathMap();
        groupLogPathMapCenter.putAll(groupLogPathMap);
    }
}
